﻿using System.Windows;

namespace Socium.Documents.Sociograms {
	public static class SizeObserver {
		public static readonly DependencyProperty ObserveProperty = DependencyProperty.RegisterAttached(
			"Observe",
			typeof(bool),
			typeof(SizeObserver),
			new FrameworkPropertyMetadata(OnObserveChanged));

		public static readonly DependencyProperty ObservedWidthProperty = DependencyProperty.RegisterAttached(
			"ObservedWidth",
			typeof(double),
			typeof(SizeObserver));

		public static readonly DependencyProperty ObservedHeightProperty = DependencyProperty.RegisterAttached(
			"ObservedHeight",
			typeof(double),
			typeof(SizeObserver));

		public static bool GetObserve(FrameworkElement element) {
			return (bool)element.GetValue(ObserveProperty);
		}

		public static void SetObserve(FrameworkElement element, bool observe) {
			element.SetValue(ObserveProperty, observe);
		}

		public static double GetObservedWidth(FrameworkElement element) {
			return (double)element.GetValue(ObservedWidthProperty);
		}

		public static void SetObservedWidth(FrameworkElement element, double observed_width) {
			element.SetValue(ObservedWidthProperty, observed_width);
		}

		public static double GetObservedHeight(FrameworkElement element) {
			return (double)element.GetValue(ObservedHeightProperty);
		}

		public static void SetObservedHeight(FrameworkElement element, double observed_height) {
			element.SetValue(ObservedHeightProperty, observed_height);
		}

		private static void OnObserveChanged(DependencyObject dependency_object, DependencyPropertyChangedEventArgs e) {
			var element = (FrameworkElement)dependency_object;

			if ((bool)e.NewValue) {
				element.SizeChanged += OnFrameworkElementSizeChanged;
				UpdateObservedSizesForFrameworkElement(element);
			}
			else {
				element.SizeChanged -= OnFrameworkElementSizeChanged;
			}
		}

		private static void OnFrameworkElementSizeChanged(object sender, SizeChangedEventArgs e) {
			UpdateObservedSizesForFrameworkElement((FrameworkElement)sender);
		}

		private static void UpdateObservedSizesForFrameworkElement(FrameworkElement element) {
			// WPF 4.0 onwards
			element.SetCurrentValue(ObservedWidthProperty, element.ActualWidth);
			element.SetCurrentValue(ObservedHeightProperty, element.ActualHeight);

			// WPF 3.5 and prior
			////SetObservedWidth(element, element.ActualWidth);
			////SetObservedHeight(element, element.ActualHeight);
		}
	}
}
